var util=require("util");

//log level
var LEVEL={
	ALL:Infinity,
	INFO:3,
	WARN:2,
	ERROR:1,
	NONE:-Infinity
};

//log color
var COLOR={
	RESET:'\u001b[0m',
	INFO:'\u001b[32m',
	WARN:'\u001b[33m',
	ERROR:'\u001b[31m'
};

//global log level
var globalLevel=LEVEL.ALL;

//whether log output should be colored
var coloredOutput=true;

function setLevel(Level){
	globalLevel=level;
}

function setColoredOutput(bool){
	coloredOutput=bool;
}

function info(){
	if (LEVEL.INFO<=globalLevel){
		log(LEVEL.INFO,util.format.apply(this,arguments));
	}
}

function warn(){
	if (LEVEL.WARN<=globalLevel){
		log(LEVEL.WARN,util.format.apply(this,arguments));
	}
}

function error(){
	if (LEVEL.ERROR<=globalLevel){
		log(LEVEL.ERROR,util.format.apply(this,arguments));
	}
}

function newPrepareStackTrace(error,structuredStack){
	return structuredStack;
}

function log(level,message){
	var oldPrepareStackTrace=Error.prepareStackTrace;
	Error.prepareStackTrace=newPrepareStackTrace;
	var structuredStack=new Error().stack;
	Error.prepareStackTrace=oldPrepareStackTrace;
	var caller=structuredStack[2];

	var lineSep=process.platform == 'win32' ? '\\':'/';
	var fileNameSplited=caller.getFileName().split(lineSep);
	var fileName=fileNameSplited[fileNameSplited.length-1];
	var lineNumber=caller.getLineNumber();
	var columnNumber=caller.getColumnNumber();

	var levelString;
	switch(level){
		case LEVEL.INFO:
			levelString='[INFO]';
			break;
		case LEVEL.WARN:
			levelString='[WARN]';
			break;
		case LEVEL.ERROR:
			levelString='[ERROR]';
			break;
		default:
			levelString='[]';
			break;
	}
	var output=util.format('%s %s(%d,%d) %s',
		levelString,fileName,lineNumber,columnNumber,message);
	if (!coloredOutput){
		process.stdout.write(output+'\n');
	}
	else{
		switch(level){
			case LEVEL.INFO:
				process.stdout.write(COLOR.INFO+output+COLOR.RESET+'\n');
				break;
			case LEVEL.WARN:
				process.stdout.write(COLOR.WARN+output+COLOR.RESET+'\n');
				break;
			case LEVEL.ERROR:
				process.stdout.write(COLOR.ERROR+output+COLOR.RESET+'\n');
				break;
			default:
				break;
		}
	}
}

module.exports={
	info:info,
	warn:warn,
	error:error,
	LEVEL:LEVEL,
	setLevel:setLevel,
	setColoredOutput:setColoredOutput
};